﻿using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Resources;
using System.Threading;
using System.Windows;

namespace Zuehlke.Blueprint.Quickstart.Architecture.Presentation.UserInterface.Localization
{
    /// <summary>
    /// The translation manager.
    /// </summary>
    /// <remarks>Example implementation using RESX files as translation sources.</remarks>
    public static class TranslationManager
    {
        #region Private Members

        private static readonly Dictionary<CultureInfo, ResourceSet> ResourceSets = new Dictionary<CultureInfo, ResourceSet>();
        private static ResourceManager _resourceManager;
        
        #endregion

        #region Attached Properties

        #region Language

        /// <summary>
        /// Represents the language used for translation.
        /// </summary>
        public static readonly DependencyProperty LanguageProperty = DependencyProperty.RegisterAttached(
            "Language",
            typeof(CultureInfo),
            typeof(TranslationManager),
            new FrameworkPropertyMetadata(CultureInfo.CurrentUICulture, FrameworkPropertyMetadataOptions.Inherits));

        /// <summary>
        /// Gets the value of the <see cref="LanguageProperty"/> attached property.
        /// </summary>
        public static CultureInfo GetLanguage(DependencyObject target)
        {
            return (CultureInfo)target.GetValue(LanguageProperty);
        }

        /// <summary>
        /// Sets the <see cref="LanguageProperty"/> attached property.
        /// </summary>
        public static void SetLanguage(DependencyObject target, CultureInfo value)
        {
            target.SetValue(LanguageProperty, value);
        }

        /// <summary>
        /// The property path which leads to the current language.
        /// </summary>.
        public static readonly PropertyPath TranslationLanguagePath = new PropertyPath(LanguageProperty);

        #endregion

        #endregion

        /// <summary>
        /// Initializes the <see cref="TranslationManager"/>.
        /// </summary>
        /// <param name="baseName">Name of the base.</param>
        /// <param name="assembly">The assembly.</param>
        public static void Initialize(string baseName, Assembly assembly)
        {
            _resourceManager = new ResourceManager(baseName, assembly);
            InitializeResourceSets();
        }

        public static object Translate(string key)
        {
            return Translate(key, Thread.CurrentThread.CurrentUICulture);
        }

        public static object Translate(string key, CultureInfo langauge)
        {
            ResourceSet resourceSet;
            if (!ResourceSets.TryGetValue(langauge, out resourceSet)
                && !ResourceSets.TryGetValue(langauge.Parent, out resourceSet))
            {
                return null;
            }

            return resourceSet.GetString(key);
        }

        public static IEnumerable<CultureInfo> SupportedLanguages
        {
            get
            {
                yield return new CultureInfo("de");
                yield return new CultureInfo("en");
            }
        }

        #region Private Helpers

        private static void InitializeResourceSets()
        {
            foreach (var language in SupportedLanguages)
            {
                ResourceSets.Add(language, _resourceManager.GetResourceSet(language, true, true));
            }
        }

        private static bool SupportsLanguage(CultureInfo culture)
        {
            return ResourceSets.ContainsKey(culture) || ResourceSets.ContainsKey(culture.Parent);
        }

        #endregion
    }
}